package s.k.gui.webtest.page;


import java.lang.reflect.Field;
import java.util.ArrayList;
import java.util.List;
import org.junit.Assert;
import org.openqa.selenium.By;
import org.openqa.selenium.NoSuchElementException;
import org.openqa.selenium.WebDriver;
import org.openqa.selenium.WebElement;

import s.k.gui.webtest.Allocator;
import s.k.gui.webtest.BrowserWindow;
import s.k.gui.webtest.WebDriverBrowserWindow;
import s.k.gui.webtest.basetools.SKBaseTools;
import s.k.gui.webtest.basetools.SKWindow;
import s.k.gui.webtest.constvalue.ConfigConstValue;
import s.k.gui.webtest.constvalue.ConstValue;
import s.k.gui.webtest.element.Element;
import s.k.gui.webtest.element.locator.Locator;
import s.k.gui.webtest.element.locator.LocatorChain;
import s.k.gui.webtest.element.locator.LocatorValue;
import s.k.gui.webtest.element.tools.WebDriverElementExist;
import s.k.gui.webtest.element.tools.WebElementExist;
import s.k.gui.webtest.log.MyLogger;

public class Part implements LocatorValue {
	
	private WebElementExist exist;
	
	protected MyLogger logger = MyLogger.getLogger(this.getClass());
	
	/**SubPage里面所包含的链信息<br>
	 * 用来保存这个节点所用到的comment和locator信息<br>*/
	private LocatorChain infoChain;

	public String comment;
	
	String fullName ="";
	
	public void setFullName(String fullName){
		this.fullName=fullName;
	}
	
	private int index = 1;
	
	public int getIndex() {

		return index;
	}

	public void setComment(String comment) {
		this.comment=comment;

	}
	private Locator locator;
	@Override
	public Locator getLocator() {

		return locator;
	}
	public void setLocator(Locator locator){
		
		this.locator=locator;
	}
	@Override
	public String getComment() {

		return comment;
	}

	WebElement element;
	@Override
	public WebElement getElement() {
	
		return element;
	}

	@Override
	public void setElement(WebElement element) {

		this.element = element;
	}
	
	
	String locatorCurrent="";
	@Override
	public String getLocatorCurrent() {

		return locatorCurrent;
	}

	@Override
	public void setLocatorCurrent(String locatorCurrent) {
		
		this.locatorCurrent=locatorCurrent;
	}

	public Part(String comment){
		
		this.comment=comment;
		this.infoChain=new LocatorChain();
		this.locator=new Locator();
	}
	/**
	 * 查看Collection是否存在，等待加载waitCount次
	 * */	
	private boolean isPartExist(int waitCount){
		
		BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
		
		if(currentWindow instanceof WebDriverBrowserWindow){
			
			exist=new WebDriverElementExist(this);
		}
		
		return exist.isElementExist(waitCount);
		
	}
	/**判断集合的第index个元素是否存在<br>
	 * index从1开始
	 * @param index 集合中元素的序号
	 * @return true 第index个元素存在
	 * 	false 不存在*/
	public boolean isExist(int index){
		
		if(!isExist())return false;
		
		locatorCurrent=locatorCurrent+"["+index+"]";
		
		BrowserWindow currentWindow=Allocator.getInstance().currentWindow;
		
		if(currentWindow instanceof WebDriverBrowserWindow){
			
			try{
				
				((WebDriver)currentWindow.getDriver().getEngine()).findElement(By.xpath(locatorCurrent));
				
				return true;
				
			}catch (NoSuchElementException e) {
				
				return false;
			}
			
		}return false;
	}
	
	
	/**判断此集合在其所在的页面上是否存在<br>
	 * 进行多方定位，直到找到或者所有的定位方法失败为止<br>
	 * 定位方法顺序id-name-xpath-css-link text-partial link text-tag name
	 * 默认等待加载的时间是5s，折5s不算框架本身所耗费的时间*/
	@Override
	public boolean isExist() {

		return isPartExist(ConfigConstValue.defaultWaitCount);
	}

	@Override
	public LocatorChain getInfoChain() {
	
		return infoChain;
	}
	/***Part里面等元素*/
	protected List<Element> elements=new ArrayList<Element>();
	/**Part里面的subpage*/
	protected List<SubPage> subpages=new ArrayList<SubPage>();
	/**这个集合的子集合*/
	protected List<Part> parts=new ArrayList<Part>();

	
	/**收集集合元素，这是一个简单的观察者模式的应用<br>
	 * 以此来获取页面元素的信息，在重新写locator<br>
	 * 和comment的时候用得到<br>*/
	public void init() {
		
		Field[] fields=this.getClass().getDeclaredFields();
		
		try{
			
			for(Field field : fields){
				
				if(field.getModifiers()==ConstValue.nestedFatherObjectModifier){
					
					continue;
					
				}Object o=field.get(this);
				
				if(o instanceof Element){
					
					SKBaseTools.insertElementName((Element)o, field.getName());
					
					((Element)o).getInfoChain().addParentNode(this.getInfoChain().getInfoNodes());
					
					((Element)o).setFullName(fullName+field.getName());
					
					((Element)o).getInfoChain().addNode(this);
					
					elements.add((Element)o);
					
				}else if(o instanceof SubPage){
					
					SKBaseTools.insertSubPageName((SubPage)o, field.getName());
					
					((SubPage)o).getInfoChain().addParentNode(this.getInfoChain().getInfoNodes());
					
					((SubPage)o).setFullName(fullName+field.getName());
					
					((SubPage)o).getInfoChain().addNode(this);
					
					this.subpages.add((SubPage)o);
					
					((SubPage)o).init();
					
				}else if(o instanceof Part){
					
					SKBaseTools.insertPartName((Part)o, field.getName());
					
					((Part)o).getInfoChain().addParentNode(this.getInfoChain().getInfoNodes());
					
					((Part)o).setFullName(fullName+field.getName());
					
					((Part)o).getInfoChain().addNode(this);
					
					this.parts.add((Part)o);
					
					((Part)o).init();
				}
			}		
		}catch(IllegalAccessException e){
			
			e.printStackTrace();
			
		}catch (IllegalArgumentException e) {
			
			e.printStackTrace();
		}

	}
	public void addIDLocator(String id){
		this.locator.addIdLocator(id);
	}
	public void addNameLocator(String name){
		this.locator.addNameLocator(name);
	}
	public void addXpathLocator(String xpath){
		this.locator.addXpathLocator(xpath);
	}
	public void addCSSLocator(String css){
		this.locator.addCSSLocator(css);
	}
	public void addLinkTextLocator(String linkText){
		this.locator.addLinkTextLocator(linkText);
	}
	public void addPartialLinkTextLocator(String partialLinkText){
		this.locator.addPartialLinkTextLocator(partialLinkText);
	}
	public void addAttributeLocator(String attributeName, String attributeValue) {
		this.locator.addAttributeLocator(attributeName, attributeValue);
	}
	public void addTagNameLocator(String tagName){
		this.locator.addTagNameLocator(tagName);
	}
	public void addClassLocator(String className){
		this.locator.addClassLocator(className);
	}
	/**选择集合中的第index个元素,index从1开始<br>
	 * 选中之后，该集合的对象里面的操作就针对这个元素了<br>
	 * @param index 集合中元素的序号*/
	public void select(int index){
		
		this.index=index;
	}
	/**校验集合是否存在，则失败返回*/
	public void assertExist(){
		StringBuilder message=new StringBuilder();
		if(isExist()){
			message.append(this.comment+":");
			message.append(":元素存在性校验成功！元素存在！");
			logger.info(message);
		}else{
			message.append(this.comment+":");
			message.append(":元素存在校验失败！元素不存在!");
			logger.error(message);
			SKWindow.closeAllWindows();
			Assert.fail(message.toString());
		}
	}
	/**校验集合是否不存在，则失败返回*/
	public void assertNotExist(){
		StringBuilder message=new StringBuilder();
		if(!isExist()){
			message.append(this.comment+":");
			message.append("元素不存在性校验成功！元素不存在！");
			logger.info(message);
		}else{
			message.append(this.comment+":");
			message.append("元素存在校验失败！元素存在!");
			logger.error(message);
			SKWindow.closeAllWindows();
			Assert.fail(message.toString());
		}
	}
	/**校验集合是否存在，失败继续运行*/
	public void verifyExist(){
		StringBuilder message=new StringBuilder();
		if(isExist()){
			message.append(this.comment+":");
			message.append("元素存在性校验成功！元素存在！");
			logger.info(message);
		}else{
			message.append(this.comment+":");
			message.append("元素存在校验失败！元素不存在!");
			logger.error(message);
		}
	}
	/**校验集合是否不存在，失败继续运行*/
	public void verifyNotExist(){
		StringBuilder message=new StringBuilder();
		if(!isExist()){
			message.append(this.comment+":");
			message.append("元素不存在性校验成功！元素不存在！");
			logger.info(message);
		}else{
			message.append(this.comment+":");
			message.append("元素存在校验失败！元素存在!");
			logger.error(message);
		}
	}
	
}
